<?php
/**
 * Created by PhpStorm.
 * User: stupboy
 * Date: 2018/2/8
 * Time: 16:39
 */
namespace app\api\controller;

use app\api\exception\ReturnException;
use think\Controller;
use think\Request;
use think\Config;
use app\base\service\Redis;
use think\Validate;

class Base extends Controller
{
    public $passengerInfo;
    public $driverInfo;
    public $redisPreFix = 'passenger.';
    public $redis;
    public $redisServer;
    public $ptoken;
    public $dtoken;
    public $token;
    public $key;
    public $requestMethod;
    public $dateTime;
    public $requestStatus;
    public $requestMsg;
    public $appPrefix;
    public $redisConfig;
    public $role;//1 司机 2乘客
    public $params;

    public function _initialize()
    {
        $this->redisServer   = Redis::getInstance();
        $this->redis         = $this->redisServer->redis;// new \Redis;
        $this->redisConfig   = Config('database.redis');
        $this->appPrefix     = $this->redisConfig ['prefix'];
        //$this->redis->connect($this->redisConfig ['host'],$this->redisConfig ['port']);
        $this->dtoken        = input('dtoken','');//司机token
        $this->ptoken        = input('ptoken','');//乘客token
        $this->requestMethod = Request::instance()->isPost();
        $this->dateTime      = date('Y-m-d H:i:s');
        list($this->requestStatus, $this->requestMsg) = $this->checkRequest();
    }

    // redis方法
    public function setRedis($key, $value)
    {
        $data = is_array($value) ? serialize($value) : $value;
        $this->redis->set($key, $data);
    }

    public function getRedis($key)
    {
        $value = $this->redis->get($key);
        $jsonData = unserialize($value);
        return (null === $jsonData) ? $value : $jsonData;
    }

    /**
     * 过滤请求，判断是否超时异地登入
     */
    public function checkRequest()
    {
        if(!$this->requestMethod){
            return [400,103];
        }
        if(empty($this->ptoken) && empty($this->dtoken)){
            return [0,101];
        }
        if(!empty($this->ptoken) && !empty($this->dtoken)){
            return [0,129];
        }
        // 乘客过滤
        if(!empty($this->ptoken)){
            $this->role= 2;
            $token     = substr($this->ptoken,0,32);
            $timeStamp = substr($this->ptoken,32,10);
            $areaId    = substr($this->ptoken,-1);
            $key       = $this->appPrefix.'passenger.'.$areaId.'.login';
            $info      = unserialize($this->redis->hget($key,$token));
            $loginTime = $info['loginTime'];
            if(empty($info)){
                return [0,100];
            }
            if(intval($timeStamp) != intval($loginTime)){
                return [405,120];
            }
            $this->passengerInfo = $info;
            $this->token         = $token;
            $this->key           = $key;
            $this->redis->hset($key,$token,serialize($info));
            return [1,'ok'];
        }
        // 司机过滤
        if(!empty($this->dtoken)){
            $this->role= 1;
            $token     = substr($this->dtoken,0,32);
            $timeStamp = substr($this->dtoken,32,10);
            $areaId    = substr($this->dtoken,-1);
            $key       = $this->appPrefix.'driver.'.$areaId.'.login';
            $info                  = unserialize($this->redis->hget($key,$token));
            $loginTime             = $info['loginTime'];
            if(intval($timeStamp) != intval($loginTime)){
                return [405,120];
            }
            if(empty($info) || time() - $info['activeTime'] >Config::get('login_time_expire')){
                return [406,301];
            }
            $info['activeTime']    = time();
            $this->redis->hset($key,$token,serialize($info));
            $this->driverInfo = $info;
            $this->token      = $token;
            $this->key        = $key;
            return [1,'ok'];
        }
    }

    /**
     * 权限验证
     */
    public function auth(){
        if($this->requestStatus<>1){
             abort($this->requestStatus,$this->getErrorMsg($this->requestMsg));
        }
    }

    /**
     * 成功返回
     */
    public function retSucc($data=array(),$msg='ok',$code=1){
        $info['code'] = $code;
        $info['msg']  = $msg;
        $info['time'] = time();
        $info         = array_merge($info,$data);
        return json($info);
    }

    /**
     * 成功返回不需要前面加return
     * @param $data
     * @throws ReturnException
     */
    public function success($data=[],$msg='ok',$code=1){

        throw new ReturnException('ok',1,200,$data);

    }

    /**
     * 失败返回
     */
    public function retError($msg='',$code=0){
        $info['code'] = $code;
        $info['msg']  = intval($msg)>99 ? $this->getErrorMsg($msg) : $msg;
        $info['time'] = time();
        trace($msg,'apiError');
        return json($info);
    }

    /**
     * 全部返回
     * @param int $code
     * @param string $msg
     * @param int $type
     * @return mixed
     */
    public function retAll($code=1,$msg='',$type=0){
        if($code==1){
            if(is_array($msg)){
                if($type==0){
                    return $this->retSucc(['data'=>$msg]);
                }else{
                    return $this->retSucc($msg);
                }
            }else{
                return $this->retSucc();
            }
        }else{
            return $this->retError($msg);
        }
    }

    /**
     * 错误信息代码转换
     * @param int $code
     * @return string
     */
    public function getErrorMsg($code=100){
        $errorArr = \think\Config::get('error_msg');
        if(intval($code)==0){
            return $code;
        }
        return isset($errorArr[$code]) ? $errorArr[$code] : 'undefine';
    }

    //登录获得token
    function CorePwd($pwd, $salt = '')
    {
        return md5(md5($pwd) . $salt);
    }

    //获取随机4~8位数
    public function sj_rand()
    {
        $numbers = range(10, 99);
        //shuffle 将数组顺序随即打乱
        shuffle($numbers);
        //array_slice 取该数组中的某一段
        $num = 4;
        $result = array_slice($numbers, 0, $num);
        $sj = join("", $result);
        return $sj;
    }

    //返回提示
    public function msg_rtn($code, $msg = '')
    {
        $info['code'] = $code;
        $info['msg'] = $msg;
        return json($info);
    }

    //返回数据
    public function rtn_data($code, $msg)
    {
        $info['code'] = $code;
        $info['data'] = $msg;
        return json($info);
    }

    /**
     * 变量批量获取 及 校验变量
     * @param string $string
     * @param string $method
     * @return array
     */
    public function getBatchParam($string='',$method=''){
        // order_id|1|oid#订单id@require|email/order_no#单号@require|email
        $data = [];
        $arr  = explode('/',$string);
        $rule = [];
        foreach ($arr as $v){
            $ruleArr        = explode('#',$v);
            $arr1           = explode('|',$ruleArr[0]);
            $name           = ($arr1[2] && $arr1[2]<>'-') ? $arr1[2] : $arr1[0];
            if(isset($ruleArr[1])){
                $holeName = explode('@',$ruleArr[1]);
                if(isset($holeName[1])){
                    $rule[$name.'|'.$holeName[0]] = $holeName[1];
                }else{
                    $rule[$name] = $holeName[0];
                }
            }
            $method         = ($arr1[3] && $arr1[3]<>'-') ? $arr1[3].'.' : $method.'.';
            $vari           = ($arr1[3] && $arr1[3]<>'-') ? $arr1[3].'.'.$arr1[0] : $arr1[0];
            $data[$name]    = isset($arr1[1]) ? input($vari,$arr1[1]) : input($vari);
        }
        if(!empty($rule)){
            $validate = new Validate($rule);
            if (!$validate->batch()->check($data)) {
                $checkMsg = $validate->getError();
                if(is_array($validate->getError())){
                    $arr = [];
                    foreach ($checkMsg as $k=>$v){
                        $arr[] = $v;
                    }
                    $checkMsg = implode(',',$arr);
                }
                abort(0,$this->getErrorMsg($checkMsg));//$this->requestStatus
            }
        }
        return $data;
    }

    public function batchParam($string,$method=''){
        return new \app\api\logic\Request($this->getBatchParam($string,$method));
    }
}
